package com.yunji.order.context.engine;

import com.google.common.collect.Maps;
import com.yunji.base.cache.BaseCache;
import com.yunji.base.domain.BelongDO;
import com.yunji.base.dto.AgentDTO;
import com.yunji.base.enums.AgentMode;
import com.yunji.base.enums.ScaleBelongTypeEnum;
import com.yunji.base.enums.ScaleTypes;
import com.yunji.common.enums.business.TradeTypes;
import com.yunji.common.model.domain.SiteDO;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.coupon.dto.OrderAmtDTO;
import com.yunji.coupon.dto.OrderScaleDTO;
import com.yunji.order.domain.OrderDO;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

/**
 * @author : peter-zhu
 * @date : 2025/3/17 09:54
 * @description : TODO
 **/
public class OrderCalculate {
    public static OrderAmtDTO calculateOrderAmt(BigDecimal price, BigDecimal costPrice, BigDecimal discountPrice,
                                                Integer productNums) {
        OrderAmtDTO optimalCouponVO = new OrderAmtDTO();
        BigDecimal nums = new BigDecimal(productNums);
        optimalCouponVO.setPrice(price.multiply(nums));
        optimalCouponVO.setDiscountAmount(discountPrice.multiply(nums));
        optimalCouponVO.setPayableAmount(optimalCouponVO.getDiscountAmount());
        optimalCouponVO.setSubtractAmount(optimalCouponVO.getPrice().subtract(optimalCouponVO.getDiscountAmount()));
        optimalCouponVO.setCostPrice(costPrice);
        return optimalCouponVO;
    }

    public static BigDecimal divide100(BigDecimal b) {
        return b.divide(new BigDecimal(100), 4, RoundingMode.DOWN);
    }

    public static Map<ScaleBelongTypeEnum, OrderScaleDTO> calculateScale(Long agentId, Long siteId, BigDecimal actualAmount) {
        AgentDTO agentDTO = BaseCache.getAgent(agentId);
        SiteDO site = BaseCache.getSite(siteId);
        BelongDO siteBelong = BaseCache.getBelong(site.getBelongId());
        Integer siteScaleType = siteBelong.getScaleType();
        BigDecimal siteScale = divide100(siteBelong.getScaleRatio());
        BigDecimal agentScale = divide100(agentDTO.getAgentScale());
        BigDecimal platformScale = divide100(agentDTO.getPlatformScale());
        Integer agentMode = agentDTO.getAgentMode();
        BigDecimal siteAmt = BigDecimal.ZERO, agentAmt = BigDecimal.ZERO, platformAmt = BigDecimal.ZERO;
        if (BeanUtils.equals(siteScaleType, ScaleTypes.RATIO.getCode(), ScaleTypes.CONTRACT.getCode())) {
            siteAmt = actualAmount.multiply(siteScale);
        }
        if (BeanUtils.equals(AgentMode.SELF_SUPPORT.getCode(), agentMode)) {
            agentAmt = actualAmount.multiply(agentScale);
            platformAmt = actualAmount.subtract(agentAmt).subtract(siteAmt);
            platformScale = BigDecimal.ONE.subtract(agentScale).subtract(siteScale);

        } else if (BeanUtils.equals(AgentMode.AGENT_SUPPORT.getCode(), agentMode)) {
            platformAmt = actualAmount.multiply(platformScale);
            agentAmt = actualAmount.subtract(platformAmt).subtract(siteAmt);
            agentScale = BigDecimal.ONE.subtract(platformScale).subtract(siteScale);
        }
        Map<ScaleBelongTypeEnum, OrderScaleDTO> maps = Maps.newHashMap();
        maps.put(ScaleBelongTypeEnum.PLATE, new OrderScaleDTO(agentMode, TradeTypes.PLATE.getCode(), ScaleTypes.RATIO.getCode(),
                platformScale, platformAmt));
        maps.put(ScaleBelongTypeEnum.AGENT, new OrderScaleDTO(agentMode, TradeTypes.AGENT_SCALE.getCode(), ScaleTypes.RATIO.getCode(),
                agentScale, agentAmt, agentDTO));
        maps.put(ScaleBelongTypeEnum.SITE, new OrderScaleDTO(agentMode, TradeTypes.SITE_SCALE.getCode(), siteScaleType,
                siteScale, siteAmt, site, siteBelong));
        return maps;
    }

    public static Map<ScaleBelongTypeEnum, OrderScaleDTO> calculateOrderScale(OrderDO order) {
        return calculateScale(order.getAgentId(), order.getSiteId(), order.getActualAmount());
    }

}
